/* CsJni - .NET / Java Bridge
 * 
 * Copyright 2010 Robert E. Burke Licensed under the Apache License, Version 
 * 2.0 (the "License"); you may not use this file except in compliance with 
 * the License. You may obtain a copy of the License at 
 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable 
 * law or agreed to in writing, software distributed under the License is 
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
 * KIND, either express or implied. See the License for the specific language 
 * governing permissions and limitations under the License. 
*/

using System;
using System.Collections.Generic;
using System.Text;

namespace CsJni
{
    public sealed class JniThreadMonitor : IDisposable
    {
        private JniEnvironment mEnvironment;
        private JniObject mObjectHandle;

        internal JniThreadMonitor(JniEnvironment env, JniObject objectHandle)
        {
            JniObject.VerifyInputJniObject(objectHandle);
            mEnvironment = env;
            mObjectHandle = objectHandle;
            Enter();
        }

        ~JniThreadMonitor()
        {
            Dispose(false);
        }

        private void Enter()
        {
            int result = JniEnvironment.Functions.MonitorEnter(mEnvironment.Handle, mObjectHandle.Handle);
            if (0 != result)
            {
                JniException.CheckErrorCode(mEnvironment, result);
            }
            // EXCEPTION CHECK: Do nothing, already checked for exception above.
        }

        private void Exit()
        {
            int result = JniEnvironment.Functions.MonitorExit(mEnvironment.Handle, mObjectHandle.Handle);
            if (0 != result)
            {
                JniException.CheckErrorCode(mEnvironment, result);
            }
            // EXCEPTION CHECK: Do nothing, already checked for exception above.
            mObjectHandle = null;
        }

        private void Dispose(bool disposing)
        {
            // TODO - centralize this from other classes
            if (!disposing && !Environment.HasShutdownStarted)
            {
                throw new JniException(JniResourceManager.Instance.GetString("invalidDisposableFinalizer"));
            }
            Exit();
        }

        #region IDisposable Members

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        #endregion IDisposable Members
    }
}
